package test.org.dbstar.scheduler.control;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dbstar.scheduler.beans.Catalog;
import org.dbstar.scheduler.beans.CmdJob;
import org.dbstar.scheduler.beans.CmdJobConf;
import org.dbstar.scheduler.beans.Job;
import org.dbstar.scheduler.beans.JobConf;
import org.dbstar.scheduler.control.CatalogController;
import org.dbstar.scheduler.control.JobConfController;
import org.dbstar.scheduler.control.JobController;
import org.dbstar.scheduler.control.cache.CacheableCatalogController;
import org.dbstar.scheduler.control.cache.CacheableJobConfController;
import org.dbstar.scheduler.control.db.catalog.JdbcTemplateCatalogController;
import org.dbstar.scheduler.control.db.conf.JdbcTemplateJobConfController;
import org.dbstar.scheduler.control.exception.DaoException;
import org.dbstar.scheduler.identifier.Identifier;
import org.dbstar.scheduler.identifier.IdentifierType;
import org.dbstar.scheduler.job.CmdJobFactory;
import org.dbstar.scheduler.job.IllegalFactoryException;
import org.dbstar.scheduler.job.JobStatus;

import test.org.dbstar.scheduler.SchedulerTestCase;


/**
 * 测试JobController的TestCase基类
 * 
 * @author 代波
 * @since 1.0.0
 * @version 1.0.0
 * @date 2012-4-24
 */
public abstract class JobControllerTestCase extends SchedulerTestCase {
	private CatalogController catalogController;
	private JobConfController confController;
	private JobController controller;
	private CmdJobFactory jobFactory;

	private Catalog root;
	private int rootId;
	private Identifier c1Id;
	private Identifier c2Id;
	private JobConf c1;
	private JobConf c2;

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		catalogController = new CacheableCatalogController(new JdbcTemplateCatalogController(jt));
		confController = new CacheableJobConfController(new JdbcTemplateJobConfController(jt, identifierFactory));
		controller = buildJobController();
		jobFactory = new CmdJobFactory();

		root = catalogController.getRootCatalog();
		rootId = root.getId();
		c1Id = confController.addJobConf(newCmdJobConf(rootId, "ping 1", null, "ping www.tudou.com"));
		c2Id = confController.addJobConf(newCmdJobConf(rootId, "ping 2", null, "ping www.youku.com"));
		c1 = confController.getJobConf(c1Id);
		c2 = confController.getJobConf(c2Id);
	}

	@Override
	protected void tearDown() throws Exception {
		confController = null;
		catalogController = null;
		super.tearDown();
	}

	protected abstract JobController buildJobController() throws DaoException;

	private void checkEquals(Job c1, Job c2) {
		assertEquals(c1.getIdentifier(), c2.getIdentifier());
		assertEquals(c1.getJobConfIdentifier(), c2.getJobConfIdentifier());
		assertEquals(c1.getType(), c2.getType());
		assertEquals(c1.getStatus(), c2.getStatus());
		assertEquals(c1.getParameterSize(), c2.getParameterSize());
		assertEquals(c1.getParameters(), c2.getParameters());
		assertEquals(c1.getContent(), c2.getContent());
		assertEquals(c1.getSubmitTime(), c2.getSubmitTime());
		assertEquals(c1.getLaunchTime(), c2.getLaunchTime());
		assertEquals(c1.getFinishTime(), c2.getFinishTime());
		assertEquals(c1.getResult(), c2.getResult());
		assertEquals(c1, c2);
	}

	private JobConf newCmdJobConf(int catalog, String name, String desc, String cmd) {
		CmdJobConf conf = new CmdJobConf();
		conf.setCatalog(catalog);
		conf.setName(name);
		conf.setDescription(desc);
		conf.setCmd(cmd);
		conf.setOwner("bdai");
		return conf;
	}

	public void testGetAllJobs() throws DaoException {
		List<Job> list = controller.getAllJobs();
		assertEquals(0, list.size());
	}

	public void testGetJobsByStatusNull() throws DaoException {
		try {
			controller.getJobs((JobStatus) null);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testGetJobsByConfNull() throws DaoException {
		try {
			controller.getJobs((Identifier) null);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testGetJobsByConfError() throws DaoException {
		try {
			controller.getJobs(identifierFactory.createIdentifier(IdentifierType.job));
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		} catch (IllegalFactoryException e) {
			e.printStackTrace();
		}
	}

	public void testAddJob() throws DaoException, IllegalFactoryException {
		long ct = System.currentTimeMillis();
		CmdJob newJob = jobFactory.createJob(null, c1, "bdai", ct);
		newJob.setFinalCmd("ping");
		newJob.setLaunchTime(200L);
		newJob.setFinishTime(100L);
		newJob.getResult().setExitValue(0);
		newJob.getResult().setErrorException("errorException");
		newJob.getResult().setOut("out");
		newJob.getResult().setErr("err");
		Identifier identifier = identifierFactory.createIdentifier(IdentifierType.job);
		newJob.setIdentifier(identifier);

		// 传入对象的Identifier值会被正确设置为自动生成的Identifier，且通过addJob方法返回
		assertEquals(controller.addJob(newJob), newJob.getIdentifier());

		assertNotNull(newJob.getIdentifier());// Identifier不为null
		assertNotSame(identifier, newJob.getIdentifier());// 传入对象的Identifier值会被覆盖
		assertEquals(newJob.getJobConfIdentifier(), c1Id);
		assertEquals(newJob.getType(), CmdJobConf.JOB_TYPE);
		assertEquals(newJob.getContent(), "ping");
		assertEquals(newJob.getFinalCmd(), "ping");
		assertNull(newJob.getParameters());
		assertEquals(newJob.getSubmitTime(), ct);
		assertEquals(newJob.getLaunchTime(), new Long(200L));
		assertEquals(newJob.getFinishTime(), new Long(100L));
		assertTrue(newJob.isSucceed());
		assertEquals(newJob.getResult().getExitValue(), 0);
		assertEquals(newJob.getResult().getErrorException(), "errorException");
		assertEquals(newJob.getResult().getOut(), "out");
		assertEquals(newJob.getResult().getErr(), "err");

		checkEquals(newJob, controller.getJob(newJob.getIdentifier()));

		List<Job> list = controller.getAllJobs();
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));

		list = controller.getJobs(JobStatus.init);
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));

		list = controller.getJobs(c1Id);
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));
	}

	// 其他允许Null的值
	public void testAddJobNullable() throws DaoException, IllegalFactoryException {
		CmdJob newJob = jobFactory.createJob(null, c1, "bdai");

		// 传入对象的Identifier值会被正确设置为自动生成的Identifier，且通过addJob方法返回
		assertEquals(controller.addJob(newJob), newJob.getIdentifier());

		assertNotNull(newJob.getIdentifier());// Identifier不为null
		assertEquals(newJob.getJobConfIdentifier(), c1Id);
		assertEquals(newJob.getType(), CmdJobConf.JOB_TYPE);
		assertEquals(newJob.getContent(), c1.getContent());
		assertEquals(newJob.getFinalCmd(), c1.getContent());
		assertNull(newJob.getParameters());
		assertTrue(newJob.getSubmitTime() > 0 && newJob.getSubmitTime() <= System.currentTimeMillis());
		assertNull(newJob.getLaunchTime());
		assertNull(newJob.getFinishTime());
		assertFalse(newJob.isSucceed());
		assertEquals(newJob.getResult().getExitValue(), -1);
		assertNull(newJob.getResult().getErrorException());
		assertNull(newJob.getResult().getOut());
		assertNull(newJob.getResult().getErr());

		checkEquals(newJob, controller.getJob(newJob.getIdentifier()));

		List<Job> list = controller.getAllJobs();
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));

		list = controller.getJobs(JobStatus.init);
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));

		list = controller.getJobs(c1Id);
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));
	}

	// 有参数的，但参数数量为0
	public void testAddJobWithEmptyParameters() throws DaoException, IllegalFactoryException {
		CmdJob newJob = jobFactory.createJob(null, c1, "bdai");
		Map<String, String> parameters = new HashMap<String, String>();
		newJob.setParameters(parameters);

		// 传入对象的Identifier值会被正确设置为自动生成的Identifier，且通过addJob方法返回
		assertEquals(controller.addJob(newJob), newJob.getIdentifier());

		assertNotNull(newJob.getIdentifier());// Identifier不为null
		assertEquals(newJob.getJobConfIdentifier(), c1Id);
		assertEquals(newJob.getType(), CmdJobConf.JOB_TYPE);
		assertEquals(newJob.getContent(), c1.getContent());
		assertEquals(newJob.getFinalCmd(), c1.getContent());
		assertNull(newJob.getParameters());
		assertTrue(newJob.getSubmitTime() > 0 && newJob.getSubmitTime() <= System.currentTimeMillis());
		assertNull(newJob.getLaunchTime());
		assertNull(newJob.getFinishTime());
		assertFalse(newJob.isSucceed());
		assertEquals(newJob.getResult().getExitValue(), -1);
		assertNull(newJob.getResult().getErrorException());
		assertNull(newJob.getResult().getOut());
		assertNull(newJob.getResult().getErr());

		checkEquals(newJob, controller.getJob(newJob.getIdentifier()));

		List<Job> list = controller.getAllJobs();
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));

		list = controller.getJobs(JobStatus.init);
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));

		list = controller.getJobs(c1Id);
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));
	}

	// 有参数的，且参数数量大于0
	public void testAddJobWithMoreParameters() throws Exception {
		CmdJob newJob = jobFactory.createJob(null, c1, "bdai");
		Map<String, String> parameters = new HashMap<String, String>();
		parameters.put("p1", "abc");
		parameters.put("p2", "yyyy-MM-dd");
		newJob.setParameters(parameters);

		// 传入对象的Identifier值会被正确设置为自动生成的Identifier，且通过addJob方法返回
		assertEquals(controller.addJob(newJob), newJob.getIdentifier());

		assertNotNull(newJob.getIdentifier());// Identifier不为null
		assertEquals(newJob.getJobConfIdentifier(), c1Id);
		assertEquals(newJob.getType(), CmdJobConf.JOB_TYPE);
		assertEquals(newJob.getContent(), c1.getContent());
		assertEquals(newJob.getFinalCmd(), c1.getContent());
		assertEquals(newJob.getParameterSize(), 2);
		assertEquals(newJob.getParameters(), parameters);
		assertTrue(newJob.getSubmitTime() > 0 && newJob.getSubmitTime() <= System.currentTimeMillis());
		assertNull(newJob.getLaunchTime());
		assertNull(newJob.getFinishTime());
		assertFalse(newJob.isSucceed());
		assertEquals(newJob.getResult().getExitValue(), -1);
		assertNull(newJob.getResult().getErrorException());
		assertNull(newJob.getResult().getOut());
		assertNull(newJob.getResult().getErr());

		checkEquals(newJob, controller.getJob(newJob.getIdentifier()));

		List<Job> list = controller.getAllJobs();
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));

		list = controller.getJobs(JobStatus.init);
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));

		list = controller.getJobs(c1Id);
		assertEquals(1, list.size());
		checkEquals(newJob, list.get(0));
	}

	// 测试增加conf为不存在
	public void testAddJobConfNotExist() throws DaoException, IllegalFactoryException {
		try {
			jobFactory.createJob(null, null, "bdai");
			fail("应该抛出DaoException");
		} catch (IllegalFactoryException e) {
			e.printStackTrace();
		}
	}

	public void testUpdateJob() throws Exception {
		long ct = System.currentTimeMillis();
		Identifier identifier = controller.addJob(jobFactory.createJob(null, c1, "bdai", ct));

		CmdJob editJob = (CmdJob) controller.getJob(identifier);
		editJob.setJobConfIdentifier(c2Id);
		editJob.setSubmitTime(100L);
		editJob.setLaunchTime(200L);
		editJob.setFinishTime(300L);
		editJob.setStatus(JobStatus.submit);
		editJob.setFinalCmd("ping");
		Map<String, String> parameters = new HashMap<String, String>();
		parameters.put("p1", "abc");
		parameters.put("p2", "yyyy-MM-dd");
		editJob.setParameters(parameters);
		editJob.getResult().setErrorException("errorException");
		editJob.getResult().setExitValue(0);
		editJob.getResult().setOut("out");
		editJob.getResult().setErr("err");
		controller.updateJob(editJob);

		CmdJob job = (CmdJob) controller.getJob(identifier);
		assertEquals(job.getIdentifier(), identifier);
		assertEquals(job.getJobConfIdentifier(), c1Id);// 更新不会修改JobConfIdentifier
		assertEquals(job.getType(), CmdJobConf.JOB_TYPE);
		assertEquals(job.getStatus(), JobStatus.init);// 更新不会修改status
		assertEquals(job.getContent(), "ping");
		assertEquals(job.getFinalCmd(), "ping");
		assertEquals(job.getParameterSize(), 2);
		assertEquals(job.getParameters(), parameters);
		assertEquals(job.getSubmitTime(), ct); // 更新不修改SubmitTime
		assertEquals(job.getLaunchTime(), new Long(200L));
		assertEquals(job.getFinishTime(), new Long(300L));
		assertTrue(job.isSucceed());
		assertEquals(job.getResult().getExitValue(), 0);
		assertEquals(job.getResult().getErrorException(), "errorException");
		assertEquals(job.getResult().getOut(), "out");
		assertEquals(job.getResult().getErr(), "err");

		editJob.setSubmitTime(ct);
		editJob.setJobConfIdentifier(c1Id);
		editJob.setStatus(JobStatus.init);
		checkEquals(editJob, job);

		List<Job> list = controller.getAllJobs();
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));

		list = controller.getJobs(JobStatus.init);
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));

		list = controller.getJobs(c1Id);
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));

		assertEquals(0, controller.getJobs(c2Id).size());
		assertEquals(0, controller.getJobs(JobStatus.submit).size());
	}

	public void testUpdateJobWithEmptyParameters() throws Exception {
		long ct = System.currentTimeMillis();
		Identifier identifier = controller.addJob(jobFactory.createJob(null, c1, "bdai", ct));

		CmdJob editJob = (CmdJob) controller.getJob(identifier);
		editJob.setLaunchTime(200L);
		editJob.setFinishTime(300L);
		editJob.setStatus(JobStatus.submit);
		editJob.setFinalCmd("ping");
		Map<String, String> parameters = new HashMap<String, String>();
		editJob.setParameters(parameters);
		editJob.getResult().setErrorException("errorException");
		editJob.getResult().setExitValue(0);
		editJob.getResult().setOut("out");
		editJob.getResult().setErr("err");
		controller.updateJob(editJob);

		CmdJob job = (CmdJob) controller.getJob(identifier);
		assertEquals(job.getIdentifier(), identifier);
		assertEquals(job.getJobConfIdentifier(), c1Id);// 更新不会修改JobConfIdentifier
		assertEquals(job.getType(), CmdJobConf.JOB_TYPE);
		assertEquals(job.getStatus(), JobStatus.init);// 更新不会修改status
		assertEquals(job.getContent(), "ping");
		assertEquals(job.getFinalCmd(), "ping");
		assertEquals(job.getParameterSize(), 0);
		assertNull(job.getParameters());
		assertEquals(job.getSubmitTime(), ct); // 更新不修改SubmitTime
		assertEquals(job.getLaunchTime(), new Long(200L));
		assertEquals(job.getFinishTime(), new Long(300L));
		assertTrue(job.isSucceed());
		assertEquals(job.getResult().getExitValue(), 0);
		assertEquals(job.getResult().getErrorException(), "errorException");
		assertEquals(job.getResult().getOut(), "out");
		assertEquals(job.getResult().getErr(), "err");

		editJob.setStatus(JobStatus.init);
		checkEquals(editJob, job);

		List<Job> list = controller.getAllJobs();
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));

		list = controller.getJobs(JobStatus.init);
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));

		list = controller.getJobs(c1Id);
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));

		assertEquals(0, controller.getJobs(JobStatus.submit).size());
	}

	public void testUpdateJobNullable() throws Exception {
		long ct = System.currentTimeMillis();
		CmdJob newJob = jobFactory.createJob(null, c1, "bdai", ct);
		newJob.setFinalCmd("ping");
		newJob.setLaunchTime(200L);
		newJob.setFinishTime(100L);
		newJob.getResult().setExitValue(0);
		newJob.getResult().setErrorException("errorException");
		newJob.getResult().setOut("out");
		newJob.getResult().setErr("err");
		Map<String, String> parameters = new HashMap<String, String>();
		parameters.put("p1", "abc");
		parameters.put("p2", "yyyy-MM-dd");
		newJob.setParameters(parameters);
		Identifier identifier = controller.addJob(newJob);

		CmdJob editJob = (CmdJob) controller.getJob(identifier);
		editJob.setLaunchTime(null);
		editJob.setFinishTime(null);
		editJob.setFinalCmd(null);
		editJob.setParameters(null);
		editJob.getResult().setErrorException(null);
		editJob.getResult().setExitValue(1);
		editJob.getResult().setOut(null);
		editJob.getResult().setErr(null);
		controller.updateJob(editJob);

		CmdJob job = (CmdJob) controller.getJob(identifier);
		assertEquals(job.getIdentifier(), identifier);
		assertEquals(job.getJobConfIdentifier(), c1Id);// 更新不会修改JobConfIdentifier
		assertEquals(job.getType(), CmdJobConf.JOB_TYPE);
		assertNull(job.getContent());
		assertNull(job.getFinalCmd());
		assertEquals(job.getParameterSize(), 0);
		assertNull(job.getParameters());
		assertEquals(job.getSubmitTime(), ct); // 更新不修改SubmitTime
		assertNull(job.getLaunchTime());
		assertNull(job.getFinishTime());
		assertFalse(job.isSucceed());
		assertEquals(job.getResult().getExitValue(), 1);
		assertNull(job.getResult().getErrorException());
		assertNull(job.getResult().getOut());
		assertNull(job.getResult().getErr());

		checkEquals(editJob, job);

		List<Job> list = controller.getAllJobs();
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));

		list = controller.getJobs(JobStatus.init);
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));

		list = controller.getJobs(c1Id);
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));
	}

	public void testUpdateJobConfIdentifierNull() throws Exception {
		Job job = jobFactory.createJob(null, c1, "bdai");
		try {
			controller.updateJob(job);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testUpdateJobConfIdentifierNotExist() throws DaoException, IllegalFactoryException {
		Job job = jobFactory.createJob(null, c1, "bdai");
		job.setIdentifier(identifierFactory.createIdentifier(IdentifierType.job));
		try {
			controller.updateJob(job);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testChangeJobStatus() throws Exception {
		long ct = System.currentTimeMillis();
		CmdJob newJob = jobFactory.createJob(null, c1, "bdai", ct);
		newJob.setFinalCmd("ping");
		newJob.setLaunchTime(200L);
		newJob.setFinishTime(100L);
		newJob.getResult().setExitValue(0);
		newJob.getResult().setErrorException("errorException");
		newJob.getResult().setOut("out");
		newJob.getResult().setErr("err");
		Map<String, String> parameters = new HashMap<String, String>();
		parameters.put("p1", "abc");
		parameters.put("p2", "yyyy-MM-dd");
		newJob.setParameters(parameters);
		Identifier identifier = controller.addJob(newJob);

		assertEquals(1, controller.getJobs(JobStatus.init).size());

		controller.changeJobStatus(identifier, JobStatus.submit);

		CmdJob job = (CmdJob) controller.getJob(identifier);
		assertEquals(job.getIdentifier(), identifier);
		assertEquals(job.getJobConfIdentifier(), c1Id);// 更新不会修改JobConfIdentifier
		assertEquals(job.getType(), CmdJobConf.JOB_TYPE);
		assertEquals(job.getStatus(), JobStatus.submit);
		assertEquals(job.getContent(), "ping");
		assertEquals(job.getFinalCmd(), "ping");
		assertEquals(job.getParameterSize(), 2);
		assertEquals(job.getParameters(), parameters);
		assertEquals(job.getSubmitTime(), ct); // 更新不修改SubmitTime
		assertEquals(job.getLaunchTime(), new Long(200L));
		assertEquals(job.getFinishTime(), new Long(100L));
		assertTrue(job.isSucceed());
		assertEquals(job.getResult().getExitValue(), 0);
		assertEquals(job.getResult().getErrorException(), "errorException");
		assertEquals(job.getResult().getOut(), "out");
		assertEquals(job.getResult().getErr(), "err");

		List<Job> list = controller.getAllJobs();
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));

		list = controller.getJobs(JobStatus.submit);
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));
		assertEquals(0, controller.getJobs(JobStatus.init).size());

		list = controller.getJobs(c1Id);
		assertEquals(1, list.size());
		checkEquals(job, list.get(0));
	}

	public void testChangeJobStatusIdentifierNull() throws Exception {
		try {
			controller.changeJobStatus(null, JobStatus.ready);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testChangeJobStatusIdentifierNotJob() throws Exception {
		try {
			controller.changeJobStatus(identifierFactory.createIdentifier(IdentifierType.conf), JobStatus.ready);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testChangeJobStatusIdentifierNotExist() throws Exception {
		try {
			controller.changeJobStatus(identifierFactory.createIdentifier(IdentifierType.job), JobStatus.ready);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testChangeJobStatusStatusNull() throws Exception {
		Identifier j1 = controller.addJob(jobFactory.createJob(null, c1, "bdai"));
		try {
			controller.changeJobStatus(j1, null);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testGetJobIdentifierNull() throws DaoException {
		try {
			controller.getJob(null);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testGetJobIdentifierNotJob() throws DaoException, IllegalFactoryException {
		try {
			controller.getJob(identifierFactory.createIdentifier(IdentifierType.conf));
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	public void testGetJobIdentifierNotExist() throws DaoException, IllegalFactoryException {
		assertNull(controller.getJob(identifierFactory.createIdentifier(IdentifierType.job)));
	}

	public void testGetFirstReadyJob() throws Exception {
		Identifier j1 = controller.addJob(jobFactory.createJob(null, c1, "bdai"));
		Identifier j2 = controller.addJob(jobFactory.createJob(null, c2, "bdai"));

		assertNull(controller.getFirstReadyJob());

		controller.changeJobStatus(j2, JobStatus.submit);
		controller.changeJobStatus(j2, JobStatus.ready);
		assertEquals(controller.getFirstReadyJob(), controller.getJob(j2));

		controller.changeJobStatus(j1, JobStatus.submit);
		controller.changeJobStatus(j1, JobStatus.ready);
		assertEquals(controller.getFirstReadyJob(), controller.getJob(j1));

		controller.changeJobStatus(j1, JobStatus.error);
		assertEquals(controller.getFirstReadyJob(), controller.getJob(j2));

		controller.changeJobStatus(j2, JobStatus.cancel);
		assertNull(controller.getFirstReadyJob());
	}

	public void testRemoveConfUsedByJob() throws Exception {
		Identifier c3 = confController.addJobConf(newCmdJobConf(rootId, "name", "desc", "cmd"));
		Identifier j1 = controller.addJob(jobFactory.createJob(null, confController.getJobConf(c3), "bdai"));

		try {
			confController.removeJobConf(c3);
			fail("应该抛出DaoException");
		} catch (DaoException e) {
			e.printStackTrace();
		}

		assertEquals(1, catalogController.getAllCatalogs().size());
		assertEquals(0, catalogController.getSubCatalogs(rootId).size());
		assertEquals(3, confController.getAllJobConfs().size());
		assertEquals(3, confController.getJobConfs(rootId).size());
		assertEquals(1, controller.getAllJobs().size());
		assertEquals(1, controller.getJobs(JobStatus.init).size());
		assertEquals(1, controller.getJobs(c3).size());
		assertNotNull(controller.getJob(j1));
	}
}
